let AudioPlayer;
!(function (a, b) {
    "use strict";
    if (a === window) {
        a.AudioPlayer = b;
    } else {
        AudioPlayer = b;
    }
})(this, (function () {
    var conf = null;
    function create(_conf) {
        conf = _conf;
        if (!conf || Object.keys(conf).length === 0) {
            return;
        }
        var isLegal = function (obj) {
            let __ = false;
            if (!obj) {
                __ = false;
            } else {
                if (typeof obj === 'string') {// 字符串判空
                    __ = obj.trim().length === 0;
                } else if (typeof obj === 'object' && Object.prototype.toString.call("[object object]")) { // 判断是否是对象
                    __ = Object.keys(obj).length === 0;
                } else if (typeof obj === "number" || typeof obj === 'function') {
                    __ = true;
                } else if (typeof obj === 'symbol') {
                    __ = false;
                } else {
                    __ = true;
                }
            }
            return {
                isTrue(d) {
                    if (true === __) {
                        if (d && typeof d === 'function') {
                            d(obj);
                        }
                    }
                    return this;
                },
                isFalse(d) {
                    if (false === __) {
                        if (d && typeof d === 'function') {
                            d(obj);
                        }
                    }
                    return this;
                }
            }
        }
        function $(str) {
            if (typeof str === 'string') {
                return document.querySelector(str);
            }
            return str;
        }
        conf.$ = $;
        var btn = $(conf.control['open']),
            volEl = $(conf.volumn),
            closeEl = $(conf.control['stop']),
            playBtn = $(conf.control['pause']),
            audioCtx = null,
            source = null,
            analyserNode = null,
            index = -1,
            vol = null,
            drawer = null,
            list_len = 0,
            list = null,
            isPlay = false,
            canvas = $(conf.canvas["el"]);
        function stop() {
            if (audioCtx) {
                audioCtx.close();
            }
            destroy();
        }
        function change_audio(file, check = false) {
            if (index === file.index && !check) {
                return;
            } else {
                stop();
                load_file(file.file);
            } index = file.index;
        }
        conf.__proto__.play = change_audio;
        async function open_file_dir() {
            if (!window.showDirectoryPicker) {
                console.error("当前浏览器不支持");
                return;
            }
            try {
                const picker = await showDirectoryPicker();
                if (picker) {
                    await get_dir_handler(picker);
                    list = picker.children;
                    list_len = list.length;
                    if (list && list.length > 0) {
                        isLegal(conf.listUpdate)
                            .isTrue(() => {
                                conf.listUpdate(list);
                            });

                    }
                }
            } catch (err) {
                void err;
            }
        }

        function initAudio() {
            if (window.AudioContext) {
                audioCtx = new AudioContext(); // 创建上下文
                source = audioCtx.createBufferSource(); // 创建缓冲源
                vol = audioCtx.createGain(); // 音量
                analyserNode = audioCtx.createAnalyser();
                isLegal(audioCtx)
                    .isTrue(c => {
                        c.onstatechange = function () {
                            let state = c.state === "running";
                            isLegal(conf.playStateChange).isTrue(el => {
                                el(playBtn, state);
                            });
                            if (state) {
                                _time.start();
                            } else {
                                drawer.stop();
                            }
                        };
                    });
            } else {
                console.error("初始化音频失败");
            }
        }
        // 下一曲
        function next() {
            if (list) {
                index = index < list_len ? index += 1 : list_len;
                if (list_len === index) {
                    return;
                }
                change_audio({
                    file: list[index][1],
                    name: list[index][0],
                    index: index
                }, true);
            }
        }
        // 上一曲
        function prev() {
            if (list) {
                index = index <= 0 ? 0 : index -= 1;
                if (index === 0) {
                    return;
                }
                change_audio({
                    file: list[index][1],
                    name: list[index][0],
                    index: index
                }, true);
            }
        }
        function debounce(time,) {
            let self_time = null;
            return {
                excute(call) {
                    clearTimeout(self_time);
                    self_time = setTimeout(() => {
                        if (typeof call === 'function') {
                            call();
                        }
                    }, time || 320);
                }
            }
        }
        (function () {
            drawer = draw(1600, 740);
            const de = debounce(600);
            let prevBtn = $(conf.control["prev"]);
            let nextBtn = $(conf.control["next"]);
            isLegal(prevBtn).isTrue((el) => {
                el.onclick = function () {
                    this.disabled = "disabled";
                    de.excute(() => {
                        prev();
                        this.disabled = "";
                    });
                };
            });
            isLegal(nextBtn).isTrue((el) => {
                el.onclick = function () {
                    this.disabled = "disabled";
                    de.excute(() => {
                        next();
                        this.disabled = "";
                    });
                };
            });
            isLegal(btn).isTrue(el => {
                el.onclick = open_file_dir;
            });
            isLegal(closeEl).isTrue(el => {
                el.onclick = stop;
            });
            isLegal(volEl).isTrue(el => {
                el.addEventListener("input", function () {
                    if (vol && vol.gain)
                        vol.gain.value = this.value / 100;
                });
            });
            isLegal(playBtn).isTrue(el => {
                el.onclick = pause;
            });

            isLegal(conf.onMounted).isTrue(() => {
                conf.onMounted({
                    setEffect(style) {
                        drawer.set_style(style);
                    }
                });
            });
        })();

        function destroy() {
            audioCtx = null;
            vol = null;
            source = null;
            analyserNode = null;
        }
        var _time = time();
        function load_file(file) {
            _time.stop();
            initAudio();
            let sysFile = file;
            if (sysFile && sysFile.kind === 'file') {
                try {
                    sysFile.getFile().then(res => {
                        file_to_buffer(audioCtx, res, (buffer) => {
                            if (!buffer) {
                                console.error("播放失败！");// 编码异常
                            } else {
                                source.buffer = buffer;
                                vol.gain.value = 1;
                                source
                                    .connect(analyserNode)
                                    .connect(vol)
                                    .connect(audioCtx.destination); // 重新连接
                                source.loop = false;
                                source.onended = function () {
                                    next();
                                }
                                source.playbackRate.value = 1;// 播放速度
                                source.start(0);// 开始播放
                                drawer.run();
                            }
                        });
                    });
                } catch (err) {
                    console.error("读取文件错误", err);
                }
            }
        }

        function time() {
            let time = null;
            let isCallBack = conf.timeUpdate && typeof conf.timeUpdate === 'function';
            return {
                start() {
                    this.stop();
                    time = setInterval(() => {
                        let currentTime = audioCtx.currentTime;
                        let ct = time_format(currentTime);
                        if (isCallBack) {
                            conf.timeUpdate([ct.h, ct.m, ct.s]);
                        }
                    }, 1000);
                },
                stop() {
                    clearInterval(time);
                }
            };
        }

        function time_format(second) {
            if (!second || second < 0) {
                return
            }
            let _s = parseInt(second); // to int
            let h = parseInt(_s / 3600);
            let m = parseInt(_s / 60 % 60);
            let s = parseInt(_s % 60);
            return {
                h,
                m,
                s
            }
        }


        function between(min, max, val) {
            return val > max ? max : val < min ? min : val;
        }
        /**
         * @ctx 上下文
         * @file 文件
         * @call 回调
         * */
        function file_to_buffer(ctx, file, call) {
            if (ctx && file) {
                let reader = new FileReader();
                reader.onload = function (e) {
                    let res = e.target.result;
                    if (res) {
                        ctx.decodeAudioData(res)
                            .then(bf => {
                                isLegal(call).isTrue(() => {
                                    call(bf);
                                });
                            });
                    }
                }
                reader.readAsArrayBuffer(file);
            }
        }

        async function get_dir_handler(handler) {
            if (handler.kind === 'directory') {
                const entries = await handler.entries();
                handler.children = [];
                for await (const eve of entries) {
                    handler.children.push(eve);
                    await get_dir_handler(eve);
                }
            } else {
                return;
            }
        }
        function random_int(min, max) {
            min = Math.ceil(min);
            max = Math.floor(max);
            return Math.floor(Math.random() * (max - min + 1) + min);
        }

        function pause() {
            if (audioCtx) {
                isPlay = audioCtx.state === 'running';// 轮换
                if (isPlay) { // 暂停状态
                    audioCtx.suspend();
                } else {
                    audioCtx.resume();// 播放状态
                    drawer.start();
                }
            }
            return isPlay;
        }

        /**
         * 
         * @param {*} num 创建随机颜色数量
         * @param {*} gradient 渐变对象
         * @returns 
         */
        function createLinearColor(num, gradient) {
            if (!gradient) { return null; }
            let i = 0;
            while (i < num) {
                let r = random_int(60, 255), g = random_int(60, 255), b = random_int(60, 255);
                let rgb = `rgb(${r},${g},${b})`;
                gradient.addColorStop(i / num, rgb);
                i += 1;
            }
            return gradient;
        }

        // 画板
        function draw(w = 1600, h = 200) {
            // init canvas context
            if (!canvas) {
                return;
            }
            else {
                var ctx = null;
                var data;
                var bfSize = 0;
                canvas.width = w;
                canvas.height = h;
                ctx = canvas.getContext("2d");
                let gradient = ctx.createLinearGradient(0, 0, w, h);// 创建渐变色
                const gnt = createLinearColor(5, gradient);
                let req = null;
                let offset = 4;
                const resetSymbol = Symbol('reset');
                const vmSymbol = Symbol('vm');

                const config = {
                    pole(tag) {
                        if (tag) {
                            analyserNode.getByteFrequencyData(data);// 获取音频数据
                            this[resetSymbol]();
                            for (let i = 0; i < bfSize; i++) {
                                let y = data[i] * 2;
                                let x = i * (8 + offset);
                                ctx.beginPath();
                                ctx.lineCap = "round";
                                ctx.lineWidth = 8;
                                ctx.strokeStyle = gnt;
                                ctx.moveTo(x + 8, h);
                                ctx.lineTo(x + 8, h - y);
                                ctx.stroke();
                                ctx.closePath();
                                ctx.beginPath();
                                ctx.fillStyle = gnt;
                                ctx.arc(x + 8, (h - y) - (y === 0 ? 0 : 16), 4, 0, Math.PI * 2, false);
                                ctx.fill();
                                ctx.closePath();
                            }
                        } else {
                            return this;
                        }
                    },
                    [resetSymbol]() {
                        ctx.clearRect(0, 0, w, h);
                    },
                    ring(tag) {
                        if (tag) {
                            analyserNode.getByteFrequencyData(data);
                            this[resetSymbol]();
                            for (let i = 0; i < 360; i++) {
                                let value = data[i] / 2;
                                let a = (i * 2) / 180 * Math.PI;
                                let ca = Math.cos(a);
                                let sa = Math.sin(a);
                                ctx.beginPath();
                                ctx.strokeStyle = gnt;
                                ctx.lineWidth = 4;
                                ctx.moveTo(ca * (w / 6) + w / 2, (- sa * (w / 6) + h / 2));
                                ctx.lineTo(ca * (w / 6 + value) + w / 2, (- sa * (w / 6 + value) + h / 2));
                                ctx.stroke();
                                ctx.closePath();
                            }
                        }
                        else {
                            return this;
                        }
                    },
                    [vmSymbol]: null,
                    set_style(type = "pole") {
                        
                        switch (type) {
                            case "pole":
                                this[vmSymbol] = this.pole;
                                break;
                            case "ring":
                                this[vmSymbol] = this.ring;
                                break;
                        }
                        return undefined;
                    },
                    run() {
                        if (analyserNode) {
                            analyserNode.fftSize = 512;
                            bfSize = analyserNode.fftSize;
                            data = new Uint8Array(bfSize);
                            analyserNode.frequencyBinCount = bfSize;
                            analyserNode.smoothingTimeConstant = 0.79;console.log("启动");
                            this.start();
                        } else {
                            console.log("canvas error")
                        }
                        return this;
                    },
                    _s() {
                        var _self = this;
                        if (!_self[vmSymbol] || !audioCtx) {
                            return;
                        }
                        req = requestAnimationFrame(() => _self._s());
                        _self[vmSymbol](true);
                    },
                    stop() {
                        cancelAnimationFrame(req);
                        _time.stop();
                        this[resetSymbol]();
                    },
                    start() {
                        this._s();
                        _time.start();
                    }
                };
                config.set_style("pole"); // 默认设置
                return config;
            }
        }
    }
    return {
        create
    }
})());

export default AudioPlayer



